"""
AI工具详情数据库模型
"""

import json
from datetime import datetime
from typing import Optional, List, Dict, Any

from sqlalchemy import String, Text, Integer, DateTime, JSON, Boolean, Index
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func

from config.database import Base


class AIWebDetailToolsModel(Base):
    """AI工具详情数据库模型"""
    __tablename__ = "ai_web_detail_tools"

    # 主键
    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment="工具ID")

    # 外键关联
    parent_id: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        comment="关联的工具集ID"
    )

    # 基本字段
    tool_type: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        comment="工具类型（1=基础工具,2=MCP工具）"
    )
    tool_name: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        comment="工具名称"
    )

    # 新增：服务代码字段 - 统一的查询主键
    server_code: Mapped[Optional[str]] = mapped_column(
        String(100),
        nullable=True,
        comment="服务代码（基础工具存储category_code，MCP工具存储mcp_name）"
    )

    description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, comment="工具描述")
    is_enabled: Mapped[bool] = mapped_column(
        Boolean,
        nullable=False,
        default=True,
        comment="是否启用"
    )

    # 人工交互标识字段
    human_interactive_flag: Mapped[int] = mapped_column(
        Integer,
        nullable=False,
        default=0,
        comment="人工交互标识（0=不需要人工交互,1=需要人工交互）"
    )

    # JSON配置字段
    parameters: Mapped[str] = mapped_column(JSON, nullable=True, comment="工具参数配置")

    # 时间字段
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        default=func.current_timestamp(),
        comment="创建时间"
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        nullable=False,
        default=func.current_timestamp(),
        onupdate=func.current_timestamp(),
        comment="更新时间"
    )

    # 索引和约束
    __table_args__ = (
        Index('idx_parent_id', 'parent_id'),
        Index('idx_tool_type', 'tool_type'),
        Index('idx_tool_name', 'tool_name'),
        Index('idx_server_code', 'server_code'),  # 新增server_code索引
        Index('idx_is_enabled', 'is_enabled'),
        Index('idx_parent_tool_name', 'parent_id', 'tool_name', unique=True),  # 同一工具集下工具名称唯一
        Index('idx_server_code_tool_name', 'server_code', 'tool_name'),  # 新增复合索引
        {"comment": "AI工具详情管理表"}
    )

    def __init__(self, **kwargs):
        """初始化方法"""
        # 处理parameters参数
        if 'parameters' in kwargs:
            parameters = kwargs.pop('parameters')
            if isinstance(parameters, list):
                # 如果是列表，调用set_parameters处理
                super().__init__(**kwargs)
                self.set_parameters(parameters)
            else:
                # 如果已经是JSON字符串或其他格式，直接设置
                super().__init__(**kwargs)
        else:
            super().__init__(**kwargs)

    def __repr__(self):
        return f"<AIWebDetailToolsModel(id={self.id}, parent_id={self.parent_id}, tool_type={self.tool_type}, tool_name='{self.tool_name}', server_code='{self.server_code}', is_enabled={self.is_enabled})>"

    def to_dict(self) -> dict:
        """转换为字典"""
        return {
            "id": self.id,
            "parent_id": self.parent_id,
            "tool_type": self.tool_type,
            "tool_name": self.tool_name,
            "server_code": self.server_code,
            "description": self.description,
            "is_enabled": self.is_enabled,
            "human_interactive_flag": self.human_interactive_flag,
            "parameters": self.get_parameters(),
            "tool_type_display": self.get_tool_type_display(),
            "human_interactive_display": self.get_human_interactive_display(),
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }

    def get_parameters(self) -> List[Dict[str, Any]]:
        """获取参数配置列表"""
        if isinstance(self.parameters, str):
            try:
                return json.loads(self.parameters)
            except (json.JSONDecodeError, TypeError):
                return []
        elif isinstance(self.parameters, list):
            return self.parameters
        return self.parameters or []

    def set_parameters(self, params: List[Dict[str, Any]]) -> None:
        """设置参数配置列表"""
        if params is None:
            self.parameters = None
        elif isinstance(params, list):
            self.parameters = json.dumps(params, ensure_ascii=False) if params else None
        elif isinstance(params, str):
            # 如果已经是JSON字符串，验证后直接设置
            try:
                json.loads(params)  # 验证JSON有效性
                self.parameters = params
            except (json.JSONDecodeError, TypeError):
                self.parameters = None
        else:
            # 其他类型，尝试转换为JSON
            try:
                self.parameters = json.dumps(params, ensure_ascii=False)
            except (TypeError, ValueError):
                self.parameters = None

    def is_active(self) -> bool:
        """判断工具是否处于启用状态"""
        return self.is_enabled

    def is_disabled(self) -> bool:
        """判断工具是否处于禁用状态"""
        return not self.is_enabled

    def enable(self) -> None:
        """启用工具"""
        self.is_enabled = True
        self.updated_at = datetime.now()

    def disable(self) -> None:
        """禁用工具"""
        self.is_enabled = False
        self.updated_at = datetime.now()

    def update_status(self, new_status: bool) -> None:
        """更新工具状态"""
        if not isinstance(new_status, bool):
            if isinstance(new_status, (int, str)):
                if str(new_status).lower() in ['true', '1']:
                    new_status = True
                elif str(new_status).lower() in ['false', '0']:
                    new_status = False
                else:
                    raise ValueError(f"无效的状态值: {new_status}")
            else:
                raise ValueError(f"状态值必须是布尔值，当前类型: {type(new_status)}")

        self.is_enabled = new_status
        self.updated_at = datetime.now()

    def update_parameters(self, params: List[Dict[str, Any]]) -> None:
        """更新参数配置"""
        self.set_parameters(params)
        self.updated_at = datetime.now()

    def get_parameters_count(self) -> int:
        """获取参数数量"""
        params = self.get_parameters()
        return len(params)

    def get_required_parameters_count(self) -> int:
        """获取必需参数数量"""
        params = self.get_parameters()
        return sum(1 for param in params if param.get('is_required', False))

    def find_parameter_by_name(self, param_name: str) -> Optional[Dict[str, Any]]:
        """根据参数名称查找参数"""
        params = self.get_parameters()
        for param in params:
            if param.get('param_name') == param_name:
                return param
        return None

    def add_parameter(self, param_config: Dict[str, Any]) -> None:
        """添加新参数"""
        params = self.get_parameters()

        # 检查参数名称是否已存在
        param_name = param_config.get('param_name')
        if param_name and self.find_parameter_by_name(param_name):
            raise ValueError(f"参数名称 '{param_name}' 已存在")

        params.append(param_config)
        self.set_parameters(params)
        self.updated_at = datetime.now()

    def remove_parameter(self, param_name: str) -> bool:
        """移除参数"""
        params = self.get_parameters()
        original_count = len(params)

        params = [param for param in params if param.get('param_name') != param_name]

        if len(params) < original_count:
            self.set_parameters(params)
            self.updated_at = datetime.now()
            return True
        return False

    def update_parameter(self, param_name: str, param_config: Dict[str, Any]) -> bool:
        """更新参数配置"""
        params = self.get_parameters()

        for i, param in enumerate(params):
            if param.get('param_name') == param_name:
                params[i] = param_config
                self.set_parameters(params)
                self.updated_at = datetime.now()
                return True
        return False

    def get_parameter_names(self) -> List[str]:
        """获取所有参数名称列表"""
        params = self.get_parameters()
        return [param.get('param_name', '') for param in params if param.get('param_name')]

    def get_required_parameter_names(self) -> List[str]:
        """获取必需参数名称列表"""
        params = self.get_parameters()
        return [
            param.get('param_name', '')
            for param in params
            if param.get('param_name') and param.get('is_required', False)
        ]

    def validate_parameters_json(self) -> bool:
        """验证参数配置JSON的有效性"""
        try:
            params = self.get_parameters()
            if not isinstance(params, list):
                return False

            for param in params:
                if not isinstance(param, dict):
                    return False

                # 检查必需字段
                if 'param_name' not in param or 'param_type' not in param:
                    return False

            return True
        except Exception:
            return False

    def get_tool_summary(self) -> Dict[str, Any]:
        """获取工具摘要信息"""
        return {
            "tool_name": self.tool_name,
            "description": self.description,
            "is_enabled": self.is_enabled,
            "total_parameters": self.get_parameters_count(),
            "required_parameters": self.get_required_parameters_count(),
            "parameter_names": self.get_parameter_names(),
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }

    def clone_config(self) -> Dict[str, Any]:
        """克隆工具配置（用于复制工具）"""
        return {
            "parent_id": self.parent_id,
            "tool_name": f"{self.tool_name}_copy",
            "description": self.description,
            "is_enabled": self.is_enabled,
            "parameters": self.get_parameters()
        }

    def get_tool_type_display(self) -> str:
        """获取工具类型显示字符串"""
        return "基础工具" if self.tool_type == 1 else "MCP工具"

    def is_base_tool(self) -> bool:
        """判断是否为基础工具"""
        return self.tool_type == 1

    def is_mcp_tool(self) -> bool:
        """判断是否为MCP工具"""
        return self.tool_type == 2

    def validate_tool_type(self, tool_type: int) -> bool:
        """验证工具类型是否有效"""
        return tool_type in [1, 2]

    def update_tool_type(self, new_tool_type: int) -> None:
        """更新工具类型"""
        if not self.validate_tool_type(new_tool_type):
            raise ValueError(f"无效的工具类型: {new_tool_type}，必须是 1 或 2")

        self.tool_type = new_tool_type
        self.updated_at = datetime.now()

    def get_human_interactive_display(self) -> str:
        """获取人工交互标识显示字符串"""
        return "需要人工交互" if self.human_interactive_flag == 1 else "不需要人工交互"

    def need_human_interaction(self) -> bool:
        """判断是否需要人工交互"""
        return self.human_interactive_flag == 1

    def update_human_interactive_flag(self, flag: int) -> None:
        """更新人工交互标识"""
        if flag not in [0, 1]:
            raise ValueError("人工交互标识必须是0（不需要）或1（需要）")
        self.human_interactive_flag = flag
        self.updated_at = datetime.now()

    def enable_human_interaction(self) -> None:
        """启用人工交互"""
        self.human_interactive_flag = 1
        self.updated_at = datetime.now()

    def disable_human_interaction(self) -> None:
        """禁用人工交互"""
        self.human_interactive_flag = 0
        self.updated_at = datetime.now()
